package com.sc.byahi.user.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.sc.byahi.user.client.components.HistoryTokens;
import com.sc.byahi.user.client.components.rating.NewRating;
import com.sc.byahi.user.shared.Profile;
import com.sc.byahi.user.shared.SearchBean;
import com.sc.byahi.user.shared.constants.Config;

public class SearchResultViews extends Composite implements ICleaner {

	private static SearchResultViewsUiBinder uiBinder = GWT.create(SearchResultViewsUiBinder.class);

	interface SearchResultViewsUiBinder extends UiBinder<Widget, SearchResultViews> {
	}

	@UiField
	Button map;
	@UiField
	Button list;
	@UiField
	NewRating rating;
	@UiField
	SimplePanel displayPanel;

	ProfileListView currList;
	ProfileListMapView currMap;

	public static final String LIST = "list";
	public static final String MAP = "map";
	
	String errorText = "No profiles found for this search criteria. Please change your search and try again.";
	
	private List<ProfileResultView> views = new ArrayList<ProfileResultView>();

	/**
	 * State of this is not cleaned as in case of rating change, old view must be opened after data refreshed.
	 */
	private String currDisplayView = SearchResultViews.MAP;

	/**
	 * List and map views must always be displayed together. Search result My profiles for agent and individual
	 * 
	 * @param listView
	 * @param listMapView
	 */
	public SearchResultViews() {
		initWidget(uiBinder.createAndBindUi(this));
		if (currList == null) {
			currList = new ProfileListView();
		}
		if (currMap == null) {
			currMap = new ProfileListMapView();
		}
		rating.setInitValue(Config.NO_RATING);
		rating.setDoubleClick(true);
		views.add(currList);
		views.add(currMap);
	}

	@Override
	public void clean() {
		for (ProfileResultView v : views) {
			((ICleaner) v).clean();
		}
	}

	public void showData(List<Long> result, boolean ownData) {
		if(ownData) rating.setVisible(false);
		else rating.setVisible(true);
		Collections.sort(result);// sort by id
		currList.setData(result, ownData);
		currMap.setData(result, ownData);

		String token = History.getToken();
		String[] vals = token.split(":");
		if (vals[0] != null && HistoryTokens.SEARCH_RESULT.equals(vals[0]) && vals[1] != null && !"".equals(vals[1])) {
			SearchBean s1 = UIUtil.decodeSearchBean(vals[1]);
			rating.setInitValue(s1.getRatingThreshold());
		}

		if (SearchResultViews.LIST.equals(currDisplayView)) {
			showListView();
		} else if (SearchResultViews.MAP.equals(currDisplayView)) {
			showMapView();
		}
	}

	public void profileUpdated(Profile profile, boolean isMap) {
		for (ProfileResultView v : views) {
			v.redrawProfile(profile);
		}
	}

	/**
	 * If a profile's rating is changed
	 * 
	 * @param profileId
	 * @param rating
	 */
	public void ratingChanged(Long profileId, Long rating) {
		if (rating < this.rating.getValue() || (Config.NO_RATING.equals(this.rating.getValue()) &&  rating >= Config.MIN_RATING)) {
			for (ProfileResultView v : views) {
				v.hideProfile(profileId);
			}
		}
	}

	/**
	 * If global rating value is changed.
	 * 
	 * @param currentRating
	 * @deprecated
	 */
	public void ratingThresholdChanged(Long currentRating) {
		// Go back to DB and search everything again.
		History.fireCurrentHistoryState();
		// for (ProfileResultView v : views) {
		// v.setCurrentRating(currentRating);
		// v.redrawView();
		// }
	}

	@UiHandler("map")
	void onMapClick(ClickEvent event) {
		showMapView();
		currDisplayView = SearchResultViews.MAP;
	}

	@UiHandler("list")
	void onListClick(ClickEvent event) {
		showListView();
		currDisplayView = SearchResultViews.LIST;
	}

	public void showListView() {
		displayPanel.clear();
		if (currList.isDataEmpty()) {
			Error error = new Error();
			error.setError(Error.WARNING, errorText);
			displayPanel.add(error);
		} else {
			displayPanel.add(currList);
		}
	}

	public void showMapView() {
		displayPanel.clear();
		if (currMap.isDataEmpty()) {
			Error error = new Error();
			error.setError(Error.WARNING, errorText);
			displayPanel.add(error);
		} else {
			displayPanel.add(currMap);
		}
		currMap.resize();
	}
	// public void showNoResultView() {
	// displayPanel.clear();
	// Error error = new Error();
	// error.setError(Error.WARNING, "No result found for this search criteria. Please change your search criteria and search again.");
	// displayPanel.add(error);
	// }
}
